package com.zilue.payment.gateway.manage;

import com.alibaba.fastjson.JSON;
import com.zilue.balance.domain.UserAccount;
import com.zilue.payment.gateway.domain.CorpDO;
import com.zilue.payment.gateway.domain.PayOrderDO;
import com.zilue.payment.gateway.exception.BizManagerException;
import com.zilue.payment.gateway.paramter.order.CreateParameter;
import com.zilue.payment.gateway.reurndata.PublicReturn;
import com.zilue.payment.gateway.reurndata.enums.BusinessStatusEnum;
import com.zilue.payment.gateway.reurndata.enums.RequestStatusEnum;
import com.zilue.payment.gateway.reurndata.order.CreateReturn;
import com.zilue.payment.gateway.utils.UID;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.DateFormat;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * Created by zilue on 2017/3/8.
 */
@Service
public class OrderCreateManager extends BaseManager {
    private static final Logger logger = Logger.getLogger(OrderCreateManager.class);
    private static NumberFormat numberFormat = NumberFormat.getNumberInstance();

    static {
        numberFormat.setMinimumIntegerDigits(5);
        numberFormat.setGroupingUsed(false);
    }

    public PublicReturn createOrder(CorpDO corpDO, CreateParameter createParameter) {
        PublicReturn createReturn = new PublicReturn(RequestStatusEnum.RequestSuccess);
        //1.查找预缴账户ID
        UserAccount userAccount = queryByCard(createParameter.getCard_no(), createParameter.getCard_type());
        if (userAccount == null) {
            createReturn.setBusinessStatus(BusinessStatusEnum.CardIllegal);
            return createReturn;
        }

        //2.查询&创建订单
        PayOrderDO payOrderDO = queryByOrderNo(createParameter.getOrder_no(), corpDO.getParentCorpId(), corpDO.getCorpId());
        if (payOrderDO != null) {
            if (PayOrderDO.STATUS_SUCCESS == payOrderDO.getStatus()) {
                createReturn.setBusinessStatus(BusinessStatusEnum.OrderNumberSucceed);
                return createReturn;
            } else if (PayOrderDO.STATUS_CANCLE == payOrderDO.getStatus()) {
                createReturn.setBusinessStatus(BusinessStatusEnum.OrderNumberCancled);
                return createReturn;
            } else if (PayOrderDO.STATUS_CLOSED == payOrderDO.getStatus()) {
                createReturn.setBusinessStatus(BusinessStatusEnum.OrderNumberClosed);
                return createReturn;
            } else if (PayOrderDO.STATUS_WAIT_FOR_PAY == payOrderDO.getStatus()) {
                if (!payOrderDO.getAccountId().equals(userAccount.getId()) ||
                        !payOrderDO.getTotalAmount().equals(createParameter.getTotal_amount()) ||
                        !StringUtils.equals(payOrderDO.getSubject(), createParameter.getSubject())) {
                    createReturn.setBusinessStatus(BusinessStatusEnum.OrderNumberWaitForPay);
                    return createReturn;
                } else {
                    return createDuplication(payOrderDO);
                }

            }else if (PayOrderDO.STATUS_REFUND == payOrderDO.getStatus()){
                createReturn.setBusinessStatus(BusinessStatusEnum.OrderNumberHasRefund);
                return createReturn;
            }else {
                createReturn.setBusinessStatus(BusinessStatusEnum.OrderNumberIllegal);
                return createReturn;
            }
        } else {
            return createOrder(createParameter, corpDO.getParentCorpId(), corpDO.getCorpId(), userAccount.getId(), userAccount.getUserName());
        }
    }

    private PublicReturn createDuplication(PayOrderDO payOrderDO){
        CreateReturn createReturn = new CreateReturn(RequestStatusEnum.RequestSuccess);
        createReturn.setBusinessStatus(BusinessStatusEnum.OrderCreateSuccess);
        createReturn.setOrder_no(payOrderDO.getOrderNo());
        createReturn.setOut_trade_no(payOrderDO.getOutTradeNo());
        return createReturn;
    }

    @Transactional
    private CreateReturn createOrder(CreateParameter parameter, Long corpId, Long subCorpId, String accountId, String accountName) throws BizManagerException {
        CreateReturn createReturn = new CreateReturn(RequestStatusEnum.RequestSuccess);
        PayOrderDO payOrder = getNewPayOrder(parameter, corpId, subCorpId, accountId, accountName);
        boolean insertOK = insertPayOrder(payOrder);
        if (!insertOK) {
            throw new BizManagerException(BusinessStatusEnum.Busyness);
        }
        createReturn.setBusinessStatus(BusinessStatusEnum.OrderCreateSuccess);
        createReturn.setOrder_no(payOrder.getOrderNo());
        createReturn.setOut_trade_no(payOrder.getOutTradeNo());
        return createReturn;
    }

    private PayOrderDO getNewPayOrder(CreateParameter parameter, Long corpId, Long subCorpId, String accountId, String accountName) {

        //生成平台唯一订单号
        //a.8日期时间
        DateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
        String date = dateFormat.format(new Date());

        //b.5位子机构号
        String parentCorp = numberFormat.format(subCorpId);
        String outTradeNo = date + parentCorp + UID.getUniqueId();
        //生成PayOrder
        PayOrderDO payOrder = new PayOrderDO();
        //设置机构/商户信息
        payOrder.setCorpId(corpId);
        payOrder.setSubCorpId(subCorpId);
        //设置用户信息
        payOrder.setAccountId(accountId);
        payOrder.setAccountName(accountName);
        //支付场景，业务类型
        payOrder.setPayScene(parameter.getPay_scene());
        payOrder.setOptType(parameter.getOpt_type());
        //账单信息
        payOrder.setOrderNo(parameter.getOrder_no());
        payOrder.setOutTradeNo(outTradeNo);
        //订单详细信息
        payOrder.setSubject(parameter.getSubject());
        payOrder.setTotalAmount(parameter.getTotal_amount());
        payOrder.setGoodsDetail(JSON.toJSONString(parameter.getGoods_detail()));
        //设备和操作信息
        payOrder.setOperatorId(parameter.getOperator_id());
        payOrder.setStoreId(parameter.getStore_id());
        payOrder.setTerminalId(parameter.getTerminal_id());
        //设置初始状态
        payOrder.setStatus(PayOrderDO.STATUS_WAIT_FOR_PAY);
        return payOrder;
    }

    private boolean insertPayOrder(PayOrderDO payOrder) {
        Long insert = payOrderMapper.insert(payOrder);
        if (insert > 0)
            return true;
        else
            return false;
    }

}
